<template>
  <div>
    <div class="control_wrapper" id="control_wrapper">
      <div class="control_wrapper" id="control_wrapper">
        <div class="form-item">
          <label class="label">行政区划</label>
          <ejs-dropdowntree
            id="dropdownlist"
            :fields="fields"
          ></ejs-dropdowntree>
        </div>
        <div class="form-item">
          <label class="label">开始日期</label>
          <ejs-datepicker
            id="calendar"
            :format="dateFormat"
            :value="startDate"
          ></ejs-datepicker>
        </div>
        <div class="form-item">
          <label class="label">截止日期</label>
          <ejs-datepicker
            id="calendar"
            :format="dateFormat"
            :value="endDate"
          ></ejs-datepicker>
        </div>
      </div>
    </div>
    <div class="sample-tutorial">
      <div id="ss" style="width: 100%; height: 100%"></div>
    </div>
  </div>
</template>

<script>
import Vue from 'vue'
import { DropDownTreePlugin } from '@syncfusion/ej2-vue-dropdowns'
import { DatePickerPlugin } from '@syncfusion/ej2-vue-calendars'
import { ButtonPlugin } from '@syncfusion/ej2-vue-buttons'

Vue.use(DropDownTreePlugin)
Vue.use(DatePickerPlugin)
Vue.use(ButtonPlugin)
const gss = window.GcSpread.Sheets

export default {
  data: function () {
    return {
      spread: null,
      sheet: null,
      dataSource: [],
      already: [],
      group: [],
      fields: {
        dataSource: [
          {
            nodeId: '01',
            nodeText: 'Music',
            nodeChild: [{ nodeId: '01-01', nodeText: 'Gouttes.mp3' }]
          },
          {
            nodeId: '02',
            nodeText: 'Videos',
            expanded: true,
            nodeChild: [
              { nodeId: '02-01', nodeText: 'Naturals.mp4' },
              { nodeId: '02-02', nodeText: 'Wild.mpeg' }
            ]
          },
          {
            nodeId: '03',
            nodeText: 'Documents',
            nodeChild: [
              { nodeId: '03-01', nodeText: 'Environment Pollution.docx' },
              {
                nodeId: '03-02',
                nodeText: 'Global Water, Sanitation, & Hygiene.docx'
              },
              { nodeId: '03-03', nodeText: 'Global Warming.ppt' },
              { nodeId: '03-04', nodeText: 'Social Network.pdf' },
              { nodeId: '03-05', nodeText: 'Youth Empowerment.pdf' }
            ]
          }
        ],
        value: 'nodeId',
        text: 'nodeText',
        child: 'nodeChild'
      },
      dateFormat: 'yyyy年MM月dd日',
      startDate: '2016年01月01日',
      endDate: '9998年12月31日'
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    async init() {
      this.spread = new gss.Spread(document.getElementById('ss'))
      this.spread.scrollbarMaxAlign(true) // 滚动条是否对齐视图中表单的最后一行或一列
      this.spread.scrollbarShowMax(true) // 是否基于表单全部的行列总数显示滚动条
      this.spread.tabStripVisible(false) // 工作表标签的是否显示
      this.spread.showHorizontalScrollbar(false) // 是否显示水平滚动条
      this.spread.showVerticalScrollbar(false) // 是否显示垂直滚动条

      this.sheet = this.spread.getActiveSheet()
      this.sheet.rowRangeGroup.expand(1, false)
      this.sheet.setIsProtected(true) // 表单保护
      this.sheet.protectionOption({
        // allowSelectLockedCells: false, // 是否允许用户选择被锁定的单元格
        // allowSelectUnlockedCells: false, // 是否允许用户选择未被锁定的单元格
        allowSort: false, // 是否允许用户排序
        allowFilter: false, // 是否允许用户筛选
        allowEditObjects: false, // 是否允许用户编辑浮动对象
        allowResizeRows: false, // 是否允许用户改变行高
        allowResizeColumns: false // 是否允许用户改变列宽
      })
      this.sheet.setRowHeaderVisible(false) // // 隐藏行头区域
      this.sheet.isPaintSuspended(true) // 挂起重绘机制
      this.sheet.suspendEvent() // 暂停该对象所有的事件处理
      this.sheet.showRowRangeGroup(false)
      this.sheet.rowRangeGroup.direction = gss.RangeGroupDirection.Backward // 分组折叠方式

      let header = gss.SheetArea.colHeader

      this.sheet.setColumnCount(4, header)

      this.sheet.getColumn(0).cellType(this.functionTreeNodeCellType())
      this.sheet.getColumn(0).width(300)
      this.sheet.getColumns(1, 3).width(100)

      this.sheet.addSpan(0, 0, 1, 1, header)
      this.sheet.setValue(0, 0, '任务名称', header)

      this.sheet.addSpan(0, 1, 1, 1, header)
      this.sheet.setValue(0, 1, '任务编码', header)

      this.sheet.addSpan(0, 2, 1, 1, header)
      this.sheet.setValue(0, 2, '单位', header)

      this.sheet.addSpan(0, 3, 1, 1, header)
      this.sheet.setValue(0, 3, '其他', header)

      this.dataSource = await this.requestData()

      this.loadData()

      this.sheet.resumeEvent() // 开启该对象所有的事件处理
      this.sheet.isPaintSuspended(false) // 开启重绘机制
    },
    functionTreeNodeCellType() {
      function TreeNodeCellType() {}

      TreeNodeCellType.prototype = new gss.CustomCellType()

      TreeNodeCellType.prototype.paint = function (
        ctx,
        value,
        x,
        y,
        w,
        h,
        style,
        options
      ) {
        if (!ctx || !value) return

        let level = options.sheet.rowRangeGroup.getLevel(options.row)
        x += (level + 2) * 12

        gss.CustomCellType.prototype.paint.apply(this, [
          ctx,
          value,
          x,
          y,
          w,
          h,
          style,
          options
        ])

        if (options.row > options.sheet.getRowCount() - 1) return // last row

        let collapsed = options.sheet.rowRangeGroup.isCollapsed(options.row + 1)
        x--
        y += h / 2 - 3

        ctx.save()
        ctx.fillStyle = 'black'
        ctx.beginPath()

        if (collapsed) {
          ctx.moveTo(x - 5, y)
          ctx.lineTo(x, y + 3)
          ctx.lineTo(x - 5, y + 6)
        } else {
          ctx.moveTo(x, y)
          ctx.lineTo(x, y + 5)
          ctx.lineTo(x - 5, y + 5)
        }
        ctx.fill()
        ctx.restore()
      }

      TreeNodeCellType.prototype.getHitInfo = function (
        x,
        y,
        cellStyle,
        cellRect,
        context
      ) {
        return {
          x: x,
          y: y,
          row: context.row,
          col: context.col,
          cellStyle: cellStyle,
          cellRect: cellRect,
          sheetArea: context.sheetArea
        }
      }

      let _this = this
      TreeNodeCellType.prototype.processMouseDown = async (hitinfo) => {
        let level = hitinfo.sheet.rowRangeGroup.getLevel(hitinfo.row)
        let hoffset = (level + 2) * 12 + hitinfo.cellRect.x
        if (hitinfo.x < hoffset && hitinfo.x > hoffset - 10) {
          if (_this.dataSource.length <= hitinfo.row) return // 点击的不是有数据的row

          if (_this.already.indexOf(hitinfo.row + 1) === -1) {
            const row = _this.dataSource[hitinfo.row] // 获取点击的行数据
            const data = await _this.requestData(row.name)
            _this.sheet.isPaintSuspended(true) // 挂起重绘机制
            _this.sheet.suspendEvent() // 暂停该对象所有的事件处理
            // 合并数据
            _this.dataSource.splice(hitinfo.row + 1, 0, ...data)
            // 取消原来的分组
            _this.group.forEach((item) => {
              _this.sheet.rowRangeGroup.ungroup(item[0], item[1])
            })
            // 改变原来请求数据的行数
            _this.already = _this.already.map((item) =>
              item >= hitinfo.row + 1 ? item + data.length : item
            )
            // 改变原来的分组
            _this.group.forEach((item) => {
              if (item[0] >= hitinfo.row + 1) {
                // 起始行数大于点击行数，改变起始行数
                item[0] += data.length
              }
              if (
                item[0] <= hitinfo.row + 1 &&
                item[0] + item[1] >= hitinfo.row + 1
              ) {
                // 原来分组包含当前行
                item[1] += data.length
              }
            })
            // 加载数据
            _this.loadData()
            // 添加一个新的分组
            _this.group.push([hitinfo.row + 1, data.length])
            // 创建所有分组
            _this.group.forEach((item) => {
              _this.sheet.rowRangeGroup.group(item[0], item[1])
            })
            // 在已加载分组中加入当前行
            _this.already.push(hitinfo.row + 1)
          }

          let collapsed = hitinfo.sheet.rowRangeGroup.isCollapsed(
            hitinfo.row + 1
          )
          hitinfo.sheet.rowRangeGroup.setCollapsed(hitinfo.row, !collapsed)
          hitinfo.sheet.invalidateLayout()
          hitinfo.sheet.repaint()
          this.sheet.resumeEvent() // 开启该对象所有的事件处理
          this.sheet.isPaintSuspended(false) // 开启重绘机制
        }
      }

      return new TreeNodeCellType()
    },
    loadData() {
      this.sheet.setRowCount(this.dataSource.length + 1)

      for (var i = 0; i < this.dataSource.length; i++) {
        this.sheet.setValue(i, 0, this.dataSource[i].name)
        this.sheet.setValue(i, 1, this.dataSource[i].a)
        this.sheet
          .getCell(i, 1)
          .formatter(
            new gss.GeneralFormatter('f', gss.FormatMode.StandardNumericMode)
          )
        this.sheet.setValue(i, 2, this.dataSource[i].b)
        this.sheet.setValue(i, 3, this.dataSource[i].c)
        this.sheet
          .getCell(i, 3)
          .formatter(
            new gss.GeneralFormatter('f', gss.FormatMode.StandardNumericMode)
          )
      }
    },
    async requestData() {
      const array = [
        {
          name: '01',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '02',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '03',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '04',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '05',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '06',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '07',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '08',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        },
        {
          name: '09',
          a: (500 - 1) * Math.random() + 1,
          b: 'sm',
          c: (500 - 1) * Math.random() + 1
        }
      ]

      return array
    }
  }
}
</script>

<style scoped>
.control_wrapper {
  display: flex;
  flex-wrap: wrap;
}
.form-item {
  flex: 0 0 300px;
  margin-left: 30px;
  display: flex;
  align-items: center;
}
.form-item .label {
  flex: 0 0 100px;
  position: relative;
  text-align-last: justify;
  padding-right: 20px;
  /* box-sizing: border-box; */
}
.form-item .label::after {
  content: ':';
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  width: 20px;
  display: flex;
  justify-content: center;
}
</style>
